package fun.boomcat.luckyhe.mirai.plugin.command;

import fun.boomcat.luckyhe.mirai.plugin.config.RconCommandConfigOperation;
import fun.boomcat.luckyhe.mirai.plugin.pojo.CommandMapping;
import fun.boomcat.luckyhe.mirai.plugin.pojo.Player;
import fun.boomcat.luckyhe.mirai.plugin.service.CommandMappingService;
import fun.boomcat.luckyhe.mirai.plugin.service.CommandMappingServiceImpl;
import fun.boomcat.luckyhe.mirai.plugin.service.PlayerListService;
import fun.boomcat.luckyhe.mirai.plugin.service.PlayerListServiceImpl;
import fun.boomcat.luckyhe.mirai.plugin.utils.CommandMappingUtil;
import fun.boomcat.luckyhe.mirai.plugin.utils.CommandMappingWebThread;
import fun.boomcat.luckyhe.mirai.plugin.utils.RconUtil;
import kotlin.Unit;
import kotlin.coroutines.Continuation;
import net.mamoe.mirai.console.command.CommandManager;
import net.mamoe.mirai.console.command.CommandOwner;
import net.mamoe.mirai.console.command.CommandSender;
import net.mamoe.mirai.console.command.RawCommand;
import net.mamoe.mirai.console.permission.Permission;
import net.mamoe.mirai.contact.User;
import net.mamoe.mirai.message.data.MessageChain;
import net.mamoe.mirai.message.data.SingleMessage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class PlayerMcCommand extends RawCommand {

    public PlayerMcCommand(@NotNull CommandOwner owner, @NotNull String primaryName, @NotNull String[] secondaryNames, @NotNull String usage, @NotNull String description, @NotNull Permission parentPermission, boolean prefixOptional) {
        super(owner, primaryName, secondaryNames, usage, description, parentPermission, prefixOptional);
    }

    @Nullable
    @Override
    public Object onCommand(@NotNull CommandSender commandSender, @NotNull MessageChain messageChain, @NotNull Continuation<? super Unit> continuation) {
        String commandPrefix = CommandManager.INSTANCE.getCommandPrefix();
        String primaryName = this.getPrimaryName();

        int mcLen = messageChain.toArray().length;
        if (mcLen == 0) {
            try {
                CommandMappingWebThread.showAllCommandMappings();
                Map<String, String> webMap = RconCommandConfigOperation.getWebsiteInfo();
                String host = webMap.get("host");
                int port = Integer.parseInt(webMap.get("port"));

                String res = "点击查看所有指令：http://" + host + ":" + port;
                commandSender.sendMessage(res);
            } catch (Exception e) {
                e.printStackTrace();
                commandSender.sendMessage("错误：处理失败，请重试");
            }
            return null;
        }

        PlayerListService playerListService = new PlayerListServiceImpl();
        User user = commandSender.getUser();
        long qq = user == null ? 0 : user.getId();

        Player player;
        try {
            player = playerListService.selectPlayerByQq(qq);
            if (player == null) {
                throw new Exception("未找到玩家绑定的mcid\n使用" + commandPrefix + "mc" + " setmcid 并按照指示绑定");
            }
        } catch (IOException e) {
            e.printStackTrace();
            commandSender.sendMessage("错误：处理失败，请重试");
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            commandSender.sendMessage("错误：" + e.toString());
            return null;
        }

        if (!player.getChecked()) {
            commandSender.sendMessage("玩家未完成mcid绑定");
            return null;
        }

        String mcid = player.getMcId();

        CommandMappingService mappingService = new CommandMappingServiceImpl();

        StringBuilder sb = new StringBuilder();
        for (SingleMessage singleMessage : messageChain) {
            sb.append(singleMessage).append(" ");
        }
        String source = sb.toString().trim();

        List<CommandMapping> commandMappings;
        try {
            commandMappings = mappingService.selectMatchCommandMapping(source);
        } catch (Exception e) {
            e.printStackTrace();
            commandSender.sendMessage("错误：处理失败，请重试");
            return null;
        }

//        选取参数个数相同的mapping
        List<CommandMapping> confirmMappings = new ArrayList<>();
        for (CommandMapping commandMapping : commandMappings) {
            if (commandMapping.getSplitSource().length == messageChain.size()) {
                confirmMappings.add(commandMapping);
            }
        }

        if (confirmMappings.size() > 1) {
            StringBuilder sb1 = new StringBuilder();
            sb1.append("错误：该指令有多个映射：\n");
            for (CommandMapping commandMapping : confirmMappings) {
                sb.append("玩家指令：").append(commandMapping.getSource()).append("\n");
                sb.append("映射指令：").append(commandMapping.getMapping()).append("\n");
                sb.append("指令描述：").append(commandMapping.getDescription()).append("\n");
                sb.append("\n");
            }

            commandSender.sendMessage(sb1.toString());
            return null;
        }

        if (confirmMappings.size() == 0) {
            commandSender.sendMessage("错误：无该指令");
            return null;
        }

        CommandMapping finallyConfirmCommandMapping = confirmMappings.get(0);

        String[] splitSource = finallyConfirmCommandMapping.getSplitSource();
        String[] splitMapping = finallyConfirmCommandMapping.getSplitMapping();

        StringBuilder stringBuilder = new StringBuilder();

        for (String s : splitMapping) {
            if (CommandMappingUtil.isArg(s)) {
                if (s.equals("#{playername}")) {
                    stringBuilder.append(mcid).append(" ");
                    continue;
                }

                for (int j = 0; j < splitSource.length; j++) {
                    if (splitSource[j].equals(s)) {
                        stringBuilder.append(messageChain.get(j).toString()).append(" ");
                        break;
                    }
                }
            } else {
                stringBuilder.append(s).append(" ");
            }
        }

        try {
            String res = RconUtil.sendMcCommand(stringBuilder.toString());
            commandSender.sendMessage("执行：" + stringBuilder.toString() +"\n返回结果：" + res);
        } catch (Exception e) {
            e.printStackTrace();
            commandSender.sendMessage("错误：发送指令失败，请重试");
            return null;
        }
        return null;
    }
}
